<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>memoizing</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            flex-direction: column;
        }

        #results li.pass {
            flex: 0;
            color: green;
        }

        #results li.fail {
            flex: 0;
            color: red;
            text-decoration: line-through;
        }
        #first ,#second{
            flex:0;
            margin-top: 20px;
        }
    </style>
</head>
<body>
<div id="results"></div>
<input id="first">
<input id="second">
<script>
    function assert(value, desc) {
        let li = document.createElement('li');
        li.className = value ? 'pass' : 'fail';
        li.appendChild(document.createTextNode(desc));
        document.getElementById('results').appendChild(li);
    }

    //函数存储
    let store = {
        nextId: 1,

        cache: {},

        add: function (fn) {
            if (!fn.id) {
                fn.id = store.nextId++;
                return !!(store.cache[fn.id] = fn);  //好用的布尔型转换
            }
        }
    };

    function ninja() {
    }

    assert(store.add(ninja), 'Function was safely added.');
    assert(!store.add(ninja), 'But it was only added once.');

    //素数计算及缓存记忆
    function isPrime(value) {
        if (!isPrime.answers) isPrime.answers = {};
        if (isPrime.answers[value] != null) {  //这里需要隐式的数据类型转换,不能用!==
            //笔记:在涉及到数据类型的判断语句时,注意是否可以添加绝对条件
            return isPrime.answers[value];
        }
        let prime = value != 1;
        for (let i = 2; i < value; i++) {
            if (value % i == 0) {
                prime = false;
                break;
            }
        }
        return isPrime.answers[value] = prime;
    }
    assert(isPrime(7), '7 is prime!');
    assert(isPrime.answers[7], 'The answer was cached!');

    //DOM元素缓存记忆
    function getElements(name) {
        if (!getElements.cache) getElements.cache = {};
        return getElements.cache[name] = getElements.cache[name] || document.getElementsByTagName(name);
    }

    //模拟类似数组方法
    var elems = {

        length:0, //保存元素的个数

        add:function (elem) {
            Array.prototype.push.call(this,elem);  //实现将元素添加到集合的方法
            //笔记:call将我们当前的对象也就是elems转换为push方法的上下文,然后push将elem以添加数组元素的形式添加到this中
            //由此根据push方法,会改变elems的length值,以达到模拟效果,妙哉妙哉~
        },

        gather:function (id) {
            this.add(document.getElementById(id));  //是一个gather方法,根据id值查找元素,并将其添加到集合中
        }
    };

    elems.gather('first');
    assert(elems.length === 1 && elems[0].nodeType,'Verify that we have an element in our stash.');

    elems.gather('second');
    assert(elems.length === 2 && elems[1].nodeType,'Verify the other insertion');

</script>
</body>
</html>